package com.sneaker.shower.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sneaker.shower.common.BizException;
import com.sneaker.shower.entity.domain.user.UserDO;
import com.sneaker.shower.entity.dto.UserDTO;
import com.sneaker.shower.entity.dto.WxCommonReqDTO;
import com.sneaker.shower.entity.enums.UserTypeEnum;
import com.sneaker.shower.mapstruct.UserMapStruct;
import com.sneaker.shower.service.WxUserService;
import com.sneaker.shower.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Service
@Slf4j
public class WxUserServiceImpl implements WxUserService {

    private final WxMaService wxMaService;
    private final UserServiceImpl userService;

    public WxUserServiceImpl(WxMaService wxMaService, UserServiceImpl userService) {
        this.wxMaService = wxMaService;
        this.userService = userService;
    }

    @Override
    public WxMaJscode2SessionResult login(String code) {
        if (StringUtils.isEmpty(code)) {
            throw new BizException("用户登录请求Code为空");
        }
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            log.info("sessionKey:{}\nopenid:{}", sessionInfo.getSessionKey(), sessionInfo.getOpenid());
            return sessionInfo;
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new BizException("用户信息解析异常");
        }
    }

    @Override
    public UserDTO info(WxCommonReqDTO wxCommonReqDTO) {

        // 解密用户信息

        WxMaUserInfo userInfo = wxMaService.getUserService()
                .getUserInfo(wxCommonReqDTO.getSessionKey(), wxCommonReqDTO.getEncryptedData(), wxCommonReqDTO.getIv());

        UserDTO dto;
        UserDO userDO = UserMapStruct.INSTANCE.maUser2DO(userInfo);
//        if(org.apache.commons.lang3.StringUtils.equals(wxCommonReqDTO.getUserType(),"user")){
        UserDO db = userService.getOne(new LambdaQueryWrapper<UserDO>().eq(UserDO::getOpenId, userInfo.getOpenId()));
        if (db == null) {
            db = new UserDO();
            db.setGuid(IdWorker.getId());
            db.setUserType(UserTypeEnum.NORMAL.getCode());
            db.setDelFlag(Byte.valueOf("0"));
            db.setRemarkName(userInfo.getNickName());
            db.setRemarkName(Base64Utils.encodeToString(userInfo.getNickName().getBytes()));
            if (!StringUtils.isEmpty(wxCommonReqDTO.getSceneStr())) {
                log.info("用户邀请码：{}", wxCommonReqDTO.getSceneStr());
                try {
                    db.setInvitedUserGuid(Long.parseLong(wxCommonReqDTO.getSceneStr()));
                } catch (Exception e) {
                    log.error("绑定邀请用户时发生异常，新增用户guid:{}, 邀请者key:{}", db.getGuid(), wxCommonReqDTO.getSceneStr());
                    e.printStackTrace();
                }
            }
        }
        userDO.setNickName(Base64Utils.encodeToString(userInfo.getNickName().getBytes()));
        initFromDB(userDO, db);
        userService.saveOrUpdate(userDO);
        dto = UserMapStruct.INSTANCE.do2DTO(userDO, "user");
//        }else {
//            SysUser sysUser =sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getGuid,userInfo.getGuid()));
//            if(sysUser != null){
//                dto = SysUserMapStruct.INSTANCE.do2DTO(sysUser,"sysUser");
//
//            }else {
//                sysUser = new SysUser();
//                BeanUtils.copyProperties(userInfo,sysUser);
//                SysUserService.sysUserExpiringMap.put(sysUser.getGuid(),sysUser);
//                dto = SysUserMapStruct.INSTANCE.do2DTO(sysUser,"sysUser");
//                return dto;
//            }
//        }
        dto.setTypeEnc(dto.getType());
        return dto;
    }

    private void initFromDB(UserDO userDO, UserDO db) {
        userDO.setCartGuid(db.getCartGuid());
        userDO.setGuid(db.getGuid());
        userDO.setUserType(db.getUserType());
        userDO.setAmount(db.getAmount());
        userDO.setDelFlag(db.getDelFlag());
        userDO.setRemarkName(db.getRemarkName());
        userDO.setGmtModified(LocalDateTime.now());
        userDO.setRetailFlag(db.getRetailFlag());
        userDO.setVersion(db.getVersion());
        userDO.setInvitedUserGuid(db.getInvitedUserGuid());
    }

    @Override
    public WxMaPhoneNumberInfo phone(WxCommonReqDTO wxCommonReqDTO) {
        if (!wxMaService.getUserService().checkUserInfo(wxCommonReqDTO.getSessionKey(), JacksonUtils.writeValueAsString(wxCommonReqDTO.getRawData()), wxCommonReqDTO.getSignature())) {
            throw new BizException("用户信息验证失败");
        }

        return wxMaService.getUserService()
                .getPhoneNoInfo(wxCommonReqDTO.getSessionKey(), wxCommonReqDTO.getEncryptedData(), wxCommonReqDTO.getIv());
    }
}
